package cn.fl.mcr.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.StandardEntityCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;

import cmm.mid.core.framework.page.DataResultVO;
import cmm.mid.core.framework.page.KeyValueVO;
import cmm.web.core.framework.controller.BaseController;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.mcr.constant.McrBillMConstant;
import cn.fl.mcr.service.IMcrBillMService;
import cn.fl.mcr.service.McrGraphicReportService;
import cn.fl.mcr.transform.McrLoanAccountVOTransform;
import cn.fl.mcr.util.ExcelReportUtil;
import cn.fl.mcr.vo.GraphicReportVO;
import cn.fl.mcr.vo.McrLoanAccountVO;
import cn.lionbridgecapital.loan.model.condition.GraphicReportQC;
import cn.lionbridgecapital.loan.model.condition.McrLoanAccountQC;
import cn.lionbridgecapital.loan.model.po.McrBillM;
import cn.lionbridgecapital.loan.model.utils.DateUtils;
import cn.lionbridgecapital.loan.service.api.IMcrLoanAccountApiService;
import net.sf.json.JSONArray;

/**
 * 
 * @ClassName: McrGraphicReportController
 * @Description:图形报表
 * @author: HZM
 * @date: 2020年2月28日 下午2:28:17
 *
 */
@Controller
@RequestMapping("/mcr/mcrGraphicReport")
public class McrGraphicReportController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(McrGraphicReportController.class);

	@Autowired
	private McrGraphicReportService mcrGraphicReportService;
	@Autowired
	private IMcrLoanAccountApiService publicMcrLoanAccountApiService;
	@Autowired
	private IMcrBillMService mcrBillMService;

	@RequestMapping(value = "/toListPage.do", method = { RequestMethod.GET })
	public ModelAndView toListPage(HttpServletRequest request, HttpServletResponse response) {
		ModelAndView view = new ModelAndView("mcr/mcrGraphicReport/statisticsOfManagementData");
		BaseLogUtils.info(logger, "toListPage", "跳转到列表页面.", CurrentThreadContext.getCurrentUserName());
		return view;
	}
	
	/**
	 * 
	 * @Title: getAccount   
	 * @Description:资方机构字典
	 * @param: @param request
	 * @param: @param response
	 * @param: @return      
	 * @return: List<KeyValueVO>      
	 * @throws
	 */
	@RequestMapping(value = "/getAccount.do", method = {RequestMethod.GET})
	@ResponseBody
	public List<KeyValueVO> getAccount(HttpServletRequest request, HttpServletResponse response) {
		 //资方账户
        McrLoanAccountQC accountQc = new McrLoanAccountQC();
        List<McrLoanAccountVO> accountList = McrLoanAccountVOTransform.toVOList(publicMcrLoanAccountApiService.searchMcrLoanAccountDTOList(accountQc));
        List<KeyValueVO> kvList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(accountList)) {
        	for(McrLoanAccountVO vo:accountList) {
        		KeyValueVO keyValueVO = new KeyValueVO();
				keyValueVO.setKey(String.valueOf(vo.getId()));
				keyValueVO.setValue(vo.getAccountName());
				kvList.add(keyValueVO);
        	}
        }
		return kvList;
	}

	/**
	 * 
	 * @Title: statisticsOfManagementData @Description: 资方数据统计 @param: @param
	 * request @param: @param response @param: @param
	 * modelMap @param: @return @param: @throws Exception @return:
	 * ModelAndView @throws
	 */
	@SuppressWarnings("uncheckded")
	@RequestMapping(value = "/statisticsOfManagementData.do", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public DataResultVO statisticsOfManagementData(HttpServletRequest request, HttpServletResponse response,
			ModelMap modelMap) throws Exception {
		DataResultVO dataResultVO = new DataResultVO(BaseConstant.IS_YESNO_YES,
				String.valueOf(BaseConstant.IS_YESNO_YES));
		GraphicReportQC qc = new GraphicReportQC();
		String crtTmStart = request.getParameter("crtTmStart");//开始日期
		if(StringUtils.isNotEmpty(crtTmStart)){
       	 	qc.setCrtTmStart(crtTmStart);
        }else {
        	crtTmStart = DateUtils.getCurrentDateStr(DateUtils.YYYY_MM_DD);
        }
		String crtTmEnd = request.getParameter("crtTmEnd");//结束日期
		if(StringUtils.isNotEmpty(crtTmEnd)) {
			qc.setCrtTmEnd(crtTmEnd);
		}else {
			crtTmEnd = DateUtils.getCurrentDateStr(DateUtils.YYYY_MM_DD);
		}
		
		Date startDate = DateUtils.formatStringToDate(crtTmStart,DateUtils.YYYY_MM_DD);//开始时间
		Date endDate = DateUtils.formatStringToDate(crtTmEnd,DateUtils.YYYY_MM_DD);//结束时间
		long betweenTimeDay = DateUtils.getDaysBetweenTwoDates(startDate, endDate);//开始日期至结束日期相隔天数
		if(betweenTimeDay > 31) {
			dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
			dataResultVO.setInfo("支持最长查询连续31天的数据");
			return dataResultVO;
		}
		betweenTimeDay = betweenTimeDay + 1;//统计天数
		
		String accountIdList = request.getParameter("accountName");//资方
		String accountNames ="";//资方
		BaseLogUtils.info(logger, "statisticsOfManagementData", "资方参数:accountIdList" + accountIdList);
		List<Long> loanAccountIds = new ArrayList<Long>();
		StringBuffer sb = new StringBuffer();
		if(StringUtils.isNotEmpty(accountIdList)) {
			String[] accountIds = accountIdList.split(";");
			for (String accountId : accountIds) {
				loanAccountIds.add(Long.valueOf(accountId));
			}
		}else {
			 McrLoanAccountQC accountQc = new McrLoanAccountQC();
		     List<McrLoanAccountVO> accountList = McrLoanAccountVOTransform.toVOList(publicMcrLoanAccountApiService.searchMcrLoanAccountDTOList(accountQc));
		     if(CollectionUtils.isNotEmpty(accountList)) {
		    	 for(McrLoanAccountVO account:accountList) {
		    		 sb.append(account.getAccountName());
		    		 sb.append("/");
		    	 }
		     }
		}
		Long availableBalance = 0l;//已选资方当前可用余额
		McrLoanAccountQC accountQc = new McrLoanAccountQC();
		accountQc.setIdList(loanAccountIds);
        List<McrLoanAccountVO> accountList = McrLoanAccountVOTransform.toVOList(publicMcrLoanAccountApiService.searchMcrLoanAccountDTOList(accountQc));
		if(CollectionUtils.isNotEmpty(accountList)) {
			for(McrLoanAccountVO vo: accountList) {
				Long availableBalance2 = vo.getAvailableBalance();
				if(null == availableBalance2) {
					availableBalance2 = 0L;
				}
				availableBalance = availableBalance + availableBalance2;
				sb.append(vo.getAccountName());
	    		sb.append("/");
			}
		}
		
		if(null != sb) {
			accountNames = sb.substring(0, sb.toString().length()-1);
		}
		
		long loanAmountBlance = 0l;//放款总额
		double averageReturn = 0;//回款总额
		
		qc.setLoanAccountIds(loanAccountIds);
		List<String> stsCdList = new ArrayList<String>();
		stsCdList.add(McrBillMConstant.LOAN_STS_CD_4);	
		stsCdList.add(McrBillMConstant.LOAN_STS_CD_6);	
		stsCdList.add(McrBillMConstant.LOAN_STS_CD_7);
		stsCdList.add(McrBillMConstant.LOAN_STS_CD_8);
		qc.setLoanStsCdList(stsCdList);
		List<GraphicReportVO> graphicReportList = Lists.newArrayList();
		for(int i=0;i<betweenTimeDay;i++) {
			long dailyLoanAmountBlance = 0l;
			GraphicReportVO  graphicReportVO = new GraphicReportVO();
			Date dateAddDate = DateUtils.getDateAddDate(startDate, 5, i);//日期
			graphicReportVO.setCrtTm(DateUtils.formatDate(dateAddDate, DateUtils.YYYY_MM_DD));
			//查询日放款总额
			qc.setCrtTmStart(DateUtils.formatDateToString(dateAddDate, DateUtils.YYYY_MM_DD) );
			qc.setCrtTmEnd(DateUtils.formatDateToString(dateAddDate, DateUtils.YYYY_MM_DD));
			List<McrBillM> queryMcrBillMLActCrAmt = mcrBillMService.queryMcrBillMLActCrAmt(qc);
			if(CollectionUtils.isNotEmpty(queryMcrBillMLActCrAmt)) {
				for(McrBillM billM:queryMcrBillMLActCrAmt) {
					dailyLoanAmountBlance = dailyLoanAmountBlance + billM.getActCrAmt();
				}
				graphicReportVO.setLoanAmountBlance((new BigDecimal(dailyLoanAmountBlance).divide(new BigDecimal("1000000"),2,BigDecimal.ROUND_HALF_UP)).doubleValue());
			}else {
				graphicReportVO.setLoanAmountBlance(0.00);//日放款金额(万元)
			}
			loanAmountBlance = loanAmountBlance + dailyLoanAmountBlance;//放款总额
			
			//查询回款总额
			HashMap<String, Object> selectRecvRent = mcrBillMService.selectRecvRent(qc);
			if(null != selectRecvRent) {
				Object object = selectRecvRent.get("RECV_RENT");
				if(null != object) {
					Double valueOf = Double.valueOf(String.valueOf(object));
					double doubleValue = new BigDecimal(valueOf/10000).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
					//日回款额
					graphicReportVO.setReturnAmountBlance(doubleValue);//(万元)
					//回款总额
					averageReturn = averageReturn +valueOf;//元
				}
			}
			
			if(null == graphicReportVO.getReturnAmountBlance()) {
				graphicReportVO.setReturnAmountBlance(0.0);
			}
			graphicReportList.add(graphicReportVO);
		}
		
		
		BigDecimal dailyAverageLoan = new BigDecimal(loanAmountBlance).divide(new BigDecimal(betweenTimeDay),2,BigDecimal.ROUND_HALF_UP);//日均放款
		if(loanAmountBlance == 0) {
			dailyAverageLoan = BigDecimal.ONE;
		}
		BigDecimal dailyAverageReturn = new BigDecimal(averageReturn).divide(new BigDecimal(betweenTimeDay),2,BigDecimal.ROUND_HALF_UP);//日均回款
		if(averageReturn == 0) {
			dailyAverageReturn = BigDecimal.ONE;
		}
		//组装数据
//		BaseLogUtils.info(logger, "statisticsOfManagementData", "生成折线图数据graphicReportList:"+JSON.toJSONString(graphicReportList) ,CurrentThreadContext.getCurrentUserName());
//		JFreeChart chart = mcrGraphicReportService.createColumnarTools("已选资方数据折线图",graphicReportList);
//		//图表指定目录 
//		String graphPath = "graphicreport/"+UUID.randomUUID()+".png";
//		String graphURL = request.getSession().getServletContext().getRealPath("/")+graphPath;
//		//将图表保存到指定目录
//		saveAsFile(chart, graphURL, 620, 700);
//		BaseLogUtils.info(logger, "statisticsOfManagementData", "生成折线图路径graphURL:" + graphURL,CurrentThreadContext.getCurrentUserName());
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("availableBalance", new BigDecimal(availableBalance).divide(new BigDecimal("1000000"),2,BigDecimal.ROUND_HALF_UP));//已选资方当前可用余额
		jsonObject.put("balanceCanContinueLoanDays", new BigDecimal(availableBalance).divide(dailyAverageLoan,2,BigDecimal.ROUND_HALF_UP));//该余额可持续放款天数(不计回款)
		jsonObject.put("repayAccountMoney", (new BigDecimal(availableBalance).add(dailyAverageReturn.multiply(new BigDecimal(100)))).divide(dailyAverageLoan,2,BigDecimal.ROUND_HALF_UP));//该余额可持续放款天数(计入日均回款)
		jsonObject.put("crtTmStartDes", crtTmStart);//开始日期
		jsonObject.put("crtTmEndDes", crtTmEnd);//结束日期
		jsonObject.put("dailyAverageLoan",  dailyAverageLoan.divide(new BigDecimal("1000000"),2,BigDecimal.ROUND_HALF_UP));//已选资方日均放款
		jsonObject.put("dailyAverageReturn",dailyAverageReturn.divide(new BigDecimal("10000"),2,BigDecimal.ROUND_HALF_UP));//已选资方日均回款
//		jsonObject.put("graphPath", graphPath);
		jsonObject.put("graphicReportList", JSON.toJSON(graphicReportList));
		jsonObject.put("accountNamesList", accountNames);
		dataResultVO.setData(jsonObject);
		BaseLogUtils.info(logger, "statisticsOfManagementData", "小贷生成报表信息:" + JSON.toJSONString(dataResultVO),
				CurrentThreadContext.getCurrentUserName());
		return dataResultVO;
	}
	
	/**
	 * 
	 * @Title: saveAsFile   
	 * @Description: 保存图片路径  
	 * @param: @param chart
	 * @param: @param outputPath
	 * @param: @param weight
	 * @param: @param height      
	 * @return: void      
	 * @throws
	 */
	public void saveAsFile(JFreeChart chart, String outputPath,int weight, int height) {
		FileOutputStream out = null;
		try {
			File outFile = new File(outputPath);
			if (!outFile.getParentFile().exists()) {
				outFile.getParentFile().mkdirs();
			}else {
				//删除上次生成的图片
				File TrxFiles[] = outFile.listFiles();
				if(null != TrxFiles) {
					for(File curFile:TrxFiles ){
						curFile.delete();  
						BaseLogUtils.info(logger, "statisticsOfManagementData", "删除折线报表:"+curFile.getName() ,CurrentThreadContext.getCurrentUserName());
					}
				}
			}
			out = new FileOutputStream(outputPath);
			// 保存为PNG
			ChartUtilities.writeChartAsPNG(out, chart, weight, height);
			// 保存为JPEG
			// ChartUtilities.writeChartAsJPEG(out, chart, weight, height);
			out.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					// do nothing
				}

			}

		}

	}
	
	/**
	 * 
	 * @Title: exportexcel   
	 * @Description: TODO(这里用一句话描述这个方法的作用)   
	 * @param: @param request
	 * @param: @param response
	 * @param: @return      
	 * @return: DataResultVO      
	 * @throws
	 */
	@SuppressWarnings(value = "unchecked")
    @RequestMapping(value = "/exportexcel.do", method = {RequestMethod.POST, RequestMethod.GET})
    public void exportexcel(HttpServletRequest request, HttpServletResponse response) {
		String graphicReportList = request.getParameter("graphicReportList");
		BaseLogUtils.info(logger, "statisticsOfManagementData", "小贷生成报表exportexcel>>graphicReportList:" + graphicReportList,CurrentThreadContext.getCurrentUserName());
		String accountNames = request.getParameter("accountName");//资方
		BaseLogUtils.info(logger, "statisticsOfManagementData", "小贷生成报表exportexcel>>accountNames:" + accountNames,CurrentThreadContext.getCurrentUserName());
		StringBuffer sb = new StringBuffer();
		if(StringUtils.isEmpty(accountNames)) {
			McrLoanAccountQC accountQc = new McrLoanAccountQC();
			List<McrLoanAccountVO> accountList = McrLoanAccountVOTransform.toVOList(publicMcrLoanAccountApiService.searchMcrLoanAccountDTOList(accountQc));
			if(CollectionUtils.isNotEmpty(accountList)) {
				for(McrLoanAccountVO account:accountList) {
					sb.append(account.getAccountName());
					sb.append("/");
				}
			}
			if(null != sb) {
				accountNames = sb.substring(0, sb.length()-1);
			}
		}
		List<Map<String, Object>> content = JSONArray.fromObject(graphicReportList);
		if(CollectionUtils.isNotEmpty(content)) {
			for(Map<String, Object> m:content) {
				String formatDateToString = DateUtils.formatDateToString(new Date(Long.valueOf(String.valueOf(m.get("crtTm")))), DateUtils.YYYY_MM_DD);
				m.put("crtTm", formatDateToString);
			}
		}
		BaseLogUtils.info(logger, "exportexcel", "小贷生成报表exportexcel>>grList:" + JSON.toJSONString(content),CurrentThreadContext.getCurrentUserName());
		String[][] headers = {{"日期","回款金额(万元)","放款金额(万元)"},{"crtTm","returnAmountBlance","loanAmountBlance"}};
		BaseLogUtils.info(logger, "exportexcel", "小贷生成报表导出excel开始",CurrentThreadContext.getCurrentUserName());
		ExcelReportUtil.exportExcelReportPage("已选资方数据表", headers, content, response, request);
		BaseLogUtils.info(logger, "exportexcel", "小贷生成报表导出excel完成",CurrentThreadContext.getCurrentUserName());
	}
	
	/**
	 * 
	 * @Title: toObject   
	 * @Description: 
	 * @param: @param list
	 * @param: @return      
	 * @return: List<Object>      
	 * @throws
	 */
	public  List<Object> toObject(List<GraphicReportVO> list){
		List<Object> objlist = new ArrayList<Object>();
		for(GraphicReportVO vo : list){
			Object obj = (Object)vo;
			objlist.add(obj);
		}
		return objlist;
	}
	
	@SuppressWarnings(value = "unchecked")
    @RequestMapping(value = "/openImage.do", method = {RequestMethod.POST, RequestMethod.GET})
	@ResponseBody
	public void openImage(HttpServletRequest request, HttpServletResponse response) {
		try {
			BaseLogUtils.info(logger, "openImage", "生成报表图片开始",CurrentThreadContext.getCurrentUserName());
			OutputStream outputStream = response.getOutputStream();
			response.setContentType("image/png;charset=UTF-8");//设定输出的类型
			String graphicReportList = request.getParameter("graphicReportList");
			
			List<Map<String, Object>> content = JSONArray.fromObject(graphicReportList);
			List<GraphicReportVO> grList = Lists.newArrayList();
			if(CollectionUtils.isNotEmpty(content)) {
				for(Map<String, Object> m:content) {
					GraphicReportVO vo = new GraphicReportVO();
					vo.setLoanAmountBlance(Double.valueOf(String.valueOf(m.get("loanAmountBlance")) ));
					vo.setReturnAmountBlance(Double.valueOf(String.valueOf(m.get("returnAmountBlance")) ));
					vo.setCrtTm(DateUtils.formatDate(new Date(Long.valueOf(String.valueOf(m.get("crtTm")))), DateUtils.YYYY_MM_DD));
					grList.add(vo);
				}
			}
			
			BaseLogUtils.info(logger, "openImage", "openImage->grList:"+JSON.toJSONString(grList),CurrentThreadContext.getCurrentUserName());
			JFreeChart chart = mcrGraphicReportService.createColumnarTools("已选资方数据折线图",grList);
			ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
			ChartUtilities.writeChartAsPNG(outputStream, chart, 620, 650,info);
			outputStream.flush();
			outputStream.close();
			BaseLogUtils.info(logger, "openImage", "生成报表图片结束",CurrentThreadContext.getCurrentUserName());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
